﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Imagine;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;

///<Summary>
///A Static class responsible for creation of all entities related to 
///game and also managing Gameplay events or something else if necessary
///</Summary>
namespace Carmack
{
    #region Gameplay Enums
    public enum eMessages
    {
        Interact
    }

    public enum eGameScreens
    {
        TestScreen,
        MenuScreen,
        GamePlayScreen
    }

    //This wil be the identifier for each Render Layer
    public enum eRenderLayers
    {
        Default,
        Character,         //These will be our characters
        ObjectLayer,
        TotalLayers,
    }
    
    public enum eGameObjectType : byte
    {
        Static          = 1 << 0,
        Interactable    = 1 << 1,
        NetworkObject   = 1 << 2,
        TotalTypes
    }

    public enum eGameKeys : short
    {
        ForwardKey      = 1 << 0,
        BackwardKey     = 1 << 1,
        LeftKey         = 1 << 2,
        RightKey        = 1 << 3,
        UseKey          = 1 << 4,
        CarryKey        = 1 << 5,
        ReloadKey       = 1 << 6,
        FireKey         = 1 << 7,
        SwitchWeaponKey = 1 << 8,
        PlaceKey        = 1 << 9
        //...Any other we may want
    }
    
    public enum eCameraEffect
    {
        NoEffect,
        SmallShake,
        MediumShake,
        LargeShake,
        SimpleShake,
        FragShake
    }
    #endregion
    
   public class GameManager
    {
        #region Properties
        public CHero MyHero
        {
            get { return m_player;  }
        }

        public SpriteFont SpriteFont
        {
            get { return m_spriteFont;  }
        }
       public Dictionary<eGameKeys,Keys> ControlMap
        {
           get { return m_controlMap; }
        }
        #endregion
        
        public CHero CreateHero( string gamertag_, bool local_ )
        {
            CHero hero = new CHero("look");
            hero.Init( gamertag_ );            
            TheWorld.Instance().Add( hero, (int)eRenderLayers.Character );
            if(local_)
                m_player = hero;
            
            return m_player;
        }
        
        //This will change according to our requirements
        public CHero CreateRemoteHero( string gamerTag_ )
        {   
            CHero remoteHero = new CHero("look");
            remoteHero.Init( gamerTag_ );            
            TheWorld.Instance().Add( remoteHero, (int)eRenderLayers.Character );
            return remoteHero;
        }

        public bool SetCameraEffect(eCameraEffect effect_)    { return m_cameraManager.SetEffect(effect_);   }
        
        public bool IdentifyHero( string gamerTag_, out CRemoteHero remoteHero_ )
        {
            remoteHero_ = null;
            //Get list of characters from TheWorld() in CharacterLayer
            List<GameObject> characters = TheWorld.Instance().RenderMap[(int)eRenderLayers.Character];
           
            for (int charCount = characters.Count, i = 0; i < charCount; ++i)
            {                   
                CRemoteHero remoHero = ((CRemoteHero)characters[i]);                
                if( remoHero.GamerTag.Equals( gamerTag_ ) )
                {   
                    //This is our Hero :)
                    remoteHero_ = remoHero; 
                    return true;
                }
            }            
            return false;
        }

        public void Init()
        {
            //Gameplay Specific Initialization Here
            m_cameraManager = new GameCameraManager();
            //Like Registering your Screens, Registering Messages
            TheScreenManager.Instance().RegisterScreen( (int)eGameScreens.TestScreen, new TestScreen() );
            TheScreenManager.Instance().RegisterScreen( (int)eGameScreens.MenuScreen, new MenuScreen() );
            TheScreenManager.Instance().RegisterScreen( (int)eGameScreens.GamePlayScreen, new GamePlayScreen() );

            m_spriteFont = TheAssetManager.Instance().Load<SpriteFont>("Font");
            CreateControlMapping();
        }
      
       public void Update(GameTime gameTime_)
        {
           m_cameraManager.Update();           
        }

       public void CreateControlMapping()
       {
           m_controlMap = new Dictionary<eGameKeys,Keys>();
           m_controlMap.Add(eGameKeys.ForwardKey,       Keys.W);
           m_controlMap.Add(eGameKeys.BackwardKey,      Keys.S);
           m_controlMap.Add(eGameKeys.LeftKey,       Keys.A);
           m_controlMap.Add(eGameKeys.RightKey, Keys.D);
           m_controlMap.Add(eGameKeys.FireKey, Keys.Space );
           m_controlMap.Add(eGameKeys.ReloadKey, Keys.R);
           m_controlMap.Add(eGameKeys.SwitchWeaponKey, Keys.F);
           m_controlMap.Add(eGameKeys.UseKey, Keys.E);
           m_controlMap.Add(eGameKeys.PlaceKey, Keys.Q);
           m_controlMap.Add(eGameKeys.CarryKey, Keys.Q);
       }

        #region Private_Parts
        GameManager()
        {}
        public static GameManager Instance()
        {
            if (instance == null)
                instance = new GameManager();
            return instance;
        }
        GameCameraManager m_cameraManager;        
        static GameManager instance;
        Dictionary<eGameKeys,Keys> m_controlMap;
        SpriteFont m_spriteFont;
        CHero m_player;
                
        #endregion
    }
}
